using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PathFindingController:MonoBehaviour {

	public GameObject[] fearObjects;
	public GameObject[] attractObjects;
	public float speed;

	List<Vector2Int> path = new List<Vector2Int>();
	new Rigidbody2D rigidbody;

	public float fearRange;
	public float attractRange;

	public List<Vector2Int> positionList = new List<Vector2Int>();

	public enum AIState {
		Patrol,
		Attract,
		Fear
	}

	private void Awake() {

		rigidbody=GetComponent<Rigidbody2D>();

	}

	private void FixedUpdate() {

		currentState=AIState.Patrol;
		Vector2Int gotoPoint = Vector2Int.zero;
		Vector2Int currentPoint = Vector2Int.RoundToInt(transform.position);

		if(positionList.Count==0) {
			positionList.Add(currentPoint);
		} else {
			if(positionList.Count>1&&currentPoint==positionList[positionList.Count-2]) {
				positionList.RemoveAt(positionList.Count-1);
			} else if(currentPoint!=positionList[positionList.Count-1]) {
				positionList.Add(currentPoint);
			}
		}


		gotoPoint=positionList[0];

		foreach(var i in attractObjects) {
			if(!i) continue;

			if(!Pathfinding.PathFind(currentPoint,Vector2Int.RoundToInt(i.transform.position),ref path,CanPass,false)) continue;

			if(((Vector2)i.transform.position-(Vector2)positionList[0]).magnitude<=attractRange) {
				currentState=AIState.Attract;
				gotoPoint=Vector2Int.RoundToInt(i.transform.position);
				break;
			}
		}

		bool directFear = false;
		Transform fearNow = null;

		foreach(var i in fearObjects) {
			if(!i) continue;
			if((i.transform.position-transform.position).magnitude<=fearRange) {
				currentState=AIState.Fear;
				fearNow=i.transform;
				gotoPoint=positionList[0];

				if(((Vector2)positionList[0]-(Vector2)i.transform.position).magnitude<=fearRange) {
					directFear=true;
				}

				break;
			}
		}

		Vector2 moveTarget = Vector2.zero;

		if(currentState!=AIState.Fear) {
			bool canGoto = Pathfinding.PathFind(currentPoint,gotoPoint,ref path,CanPass);
			if(canGoto) {
				moveTarget=path.Count>0 ? path[0] : currentPoint;
			} else moveTarget=transform.position;
		} else {
			if(directFear) moveTarget=transform.position+(transform.position-fearNow.position);
			else {

				bool canGoBack = Pathfinding.PathFind(currentPoint,gotoPoint,ref path,CanPass);
				Vector2 nextPoint = path.Count>0 ? path[0] : currentPoint;
				canGoBack&=((Vector3)nextPoint-fearNow.position).magnitude>(transform.position-fearNow.position).magnitude;
				if(canGoBack) {
					moveTarget=nextPoint;
				} else {
					moveTarget=transform.position+(transform.position-fearNow.position);
				}

			}
		}

		if((rigidbody.position-moveTarget).magnitude<0.1f) {
			transform.position=moveTarget;
			rigidbody.velocity=Vector3.zero;
		} else rigidbody.velocity=(moveTarget-rigidbody.position).normalized*speed;


	}

	AIState currentState;

	bool CanPass(Vector2Int position) {

		if(currentState!=AIState.Fear) {
			foreach(var i in fearObjects) {
				if(!i) continue;
				if(((Vector2)position-(Vector2)i.transform.position).magnitude<=fearRange) return false;
			}
		}

		if(!TilemapController.CanPass(position)) return false;

		return true;
	}

}
